#ifndef __FB_DRIVER_H__
#define __FB_DRIVER_H__

#include <linux/fb.h>
#include <fcntl.h>
#include <unistd.h>
#include <strings.h>

struct frame {
	
	int x, y;
	int width, height, bytes;
	unsigned char * buffer;
}

// Globals
unsigned char * window;
int window_width, window_height, window_bytes;

void fstart()
{
	
	char fb_size[256];
	int fb_fd, fb_size_fd, fb_width, fb_height;

	fb_size_fd = open("/sys/class/graphics/fb0/virtual_size", O_RDONLY);
	read(fb_size_fd, fb_size, 255);
	close(fb_size_fd);
	fb_width = atoi(strtok(fb_size,","));
	fb_height = atoi(strtok(NULL,","));
	
	fb_fd = open(fbdev, O_RDWR);
	
	window_width = fb_width;
	window_height = fb_height;
	window_bytes = 4;
	window = (unsigned char *) mmap(0, window_width * window_height * window_bytes, PROTEC_READ | PROTEC_WRITE, MAP_SHARED, fb_fd, (off_t ) 0);


}

void fstop()
{
	munmap(window, window_width * window_ height * window_bytes);
	close(fb_fd);
	window_width = 0;
	window_heigth = 0;
	window_bytes = 0;

}

struct frame * finit(int width,int height)
{
	struct frame * f = (struct frame *) malloc(sizeof(struct frame));
	f->x = 0;
	f->y = 0;
	f->width = width;
	f->height = height;
	f->bytes = 4;
	f->buffer = (unsigned char *) malloc(width * height * bytes);
	
	return f;
}

struct frame * get_default_frame()
{
	struct frame * f = (struct frame *) malloc(sizeof(struct frame));
	f->x = 0;
	f->y = 0;
	f->width = window_width;
	f->height = window_height;
	f->bytes = window_bytes;
	f->buffer = window;	
	return f;	
}

void des_default_frame(struct frame * f)
{
	free( (void *) f);
}


void blacken(struct frame * f)
{
	memset(f->buffer, 0, f->width * f->height * f->bytes);
}

void render(struct frame * f)
{
	int i;
	for ( i = 0; i < f->height && (i + f->x) < window_height; i++)
	{ // TODO Check window wrapping around
		memcpy( &window[f->x * window_bytes + f->y * window_bytes * window_width + i * window_width * window_bytes], &f->buffer[i * f->width * f->bytes] , (size_t) (f->width * f->bytes))
	}
}

void pixel(struct frame * f,int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t t)
{
	f->buffer[x * f->bytes + y * f->width * f->bytes] = r;	
	f->buffer[1 + x * f->bytes + y * f->width * f->bytes] = g;	
	f->buffer[2 + x * f->bytes + y * f->width * f->bytes] = b;	
	f->buffer[3 + x * f->bytes + y * f->width * f->bytes] = t;	
}

void horizontal_line(struct frame * f,int x, int width, uint8_t r, uint8_t g, uint8_t b, uint8_t t)
{
	uint32_t byte;
}


#endif
